﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TextPioneer.Facade
{
	public class DataDefinition
	{
		public string DataProviderName { get; set; }
		public string DataSource { get; set; }
		public static IEnumerable<string> LexicalParse(string def)
		{
			int pos = 0;
			int state = 0;
			StringBuilder sb = new StringBuilder();
			while (pos < def.Length)
			{
				char curChar = def[pos];
				char nextChar = pos < def.Length - 1 ? def[pos + 1] : '\0';
				switch (state)
				{
 					case 0:
						if (char.IsLetter(curChar) || char.IsNumber(curChar))
							state = 1;
						else if (curChar=='=')
							state = 2;
						else if (curChar == '\"')
						{
							state = 3;
							pos++;
						}
						else if (char.IsWhiteSpace(curChar))
							pos++;
						break;
					case 1:
						if (char.IsLetter(curChar) || char.IsNumber(curChar))
						{
							sb.Append(curChar);
							pos++;
						}
						else
						{
							yield return sb.ToString();
							state = 0;
							sb.Clear();
						}
						break;
					case 2:
						{
							yield return curChar.ToString();
							state = 0;
							pos++;
						}
						break;
					case 3:
						{
							if (curChar == '\\' && nextChar == '\"')
							{
								sb.Append(nextChar);
								pos++;
							}
							else if (curChar != '\"')
								sb.Append(curChar);
							else
							{
								state = 0;
								yield return sb.ToString();
								sb.Clear();
							}
							pos++;
						}
						break;
				}
			}
		}
		public static DataDefinition Parse(string def)
		{
			var result = new DataDefinition();
			var words = LexicalParse(def);
			var enumerator = words.GetEnumerator();
			while (true)
			{
				bool hasNext = enumerator.MoveNext();
				if (hasNext)
				{
					var key = enumerator.Current;
					if (!enumerator.MoveNext() || enumerator.Current != "=")
						throw new Exception("Invalid definition file.");
					if (!enumerator.MoveNext())
						throw new Exception("Invalid definition file.");
					var value = enumerator.Current;
					switch (key)
					{
						case "DataProvider":
							result.DataProviderName = value;
							break;
						case "DataSource":
							result.DataSource = value;
							break;
						default:

							break;
					}
				}
				else
					break;
			}
			return result;
		}
	}
}
